package uebung5;

import java.io.PrintStream;

class FullArrayException extends Exception {
};

class StudDoesnExist extends Exception {
};

public class Admin {
	private BinTree<String, StudentBase> m_Studs;
	private int m_iNextFree;
	private int m_iNextMNr;

	Admin() {
		m_Studs = new BinTree<String, StudentBase>();
		m_iNextFree = 0;
		m_iNextMNr = 20000;
	}

	public StudentBase oldest() {
		return oldestYoungestHelp(0, 0, true);
	}

	public StudentBase youngest() {
		return oldestYoungestHelp(0, 0, false);
	}

	private StudentBase oldestYoungestHelp(int iOldest, int iIndex,
			boolean bOldest) {
		if (iIndex < m_iNextFree) {
			if (bOldest
					&& m_Studs.getData().get(iOldest).age() < m_Studs.getData()
							.get(iIndex).age()
					|| !bOldest
					&& m_Studs.getData().get(iOldest).age() > m_Studs.getData()
							.get(iIndex).age())
				iOldest = iIndex;
			return oldestYoungestHelp(iOldest, iIndex + 1, bOldest);
		} else
			return m_Studs.getData().get(iOldest);
	}

	public StudentBase[] bestStudents() {
		int iBestPasses = 0;
		int iNrOfBest = 0;
		for (int i = 0; i < m_iNextFree; ++i) {
			int iPasses = m_Studs.getData().get(i).nrOfPassedExams();
			if (iPasses > iBestPasses) {
				iBestPasses = iPasses;
				iNrOfBest = 1;
			} else if (iPasses == iBestPasses)
				++iNrOfBest;
		}
		StudentBase[] res = new StudentBase[iNrOfBest];
		for (int i = 0, j = 0; i < m_iNextFree; ++i) {
			int iPasses = m_Studs.getData().get(i).nrOfPassedExams();
			if (iPasses == iBestPasses)
				res[j++] = m_Studs.getData().get(i);
		}
		return res;
	}
	
	public String getDetailsOfFirstStudent(){
		//return m_Studs.getData().get(1).name()+m_Studs.getData().get(1).name();
		return m_Studs.getData().get(1).name()+m_Studs.getData().get(1).surname();
	}

	public StudentBase[] studsOfCourse(StudentBase.Course course) {
		int iCnt = 0;
		for (int i = 0; i < m_iNextFree; ++i)
			if (m_Studs.getData().get(i).course() == course)
				++iCnt;
		StudentBase[] res = new StudentBase[iCnt];
		iCnt = 0;
		for (int i = 0; i < m_iNextFree; ++i)
			if (m_Studs.getData().get(i).course() == course)
				res[iCnt++] = m_Studs.getData().get(i);
		return res;
	}

	public StudentBase[] studsWithPassedExams(int exam) {
		return studsWithPassedExams(exam, 0, 0);
	}

	public StudentBase[] studsWithPassedExams(int exam, int iIndex, int iNr) {
		if (iNr < m_Studs.getData().size()) {
			boolean bHasPassedExams = m_Studs.getData().get(iIndex)
					.hasPassedExams(exam);
			StudentBase[] res = studsWithPassedExams(exam, iIndex + 1,
					bHasPassedExams ? iNr + 1 : iNr);
			if (bHasPassedExams)
				res[iNr] = m_Studs.getData().get(iIndex);
			return res;
		} else
			return new StudentBase[iNr];
	}

	public float averageAge() {
		float fRes = 0.0f;
		for (int i = 0; i < m_iNextFree; ++i)
			fRes += m_Studs.getData().get(i).age();
		return fRes;
	}

	public void addStud(StudentBase.Course course, String name, String surname,
			Date birth) {
		if (m_iNextFree < m_Studs.getData().size()) {
			switch (course) {
			case INF:
				m_Studs.insert(name + surname, new InfStud(m_iNextMNr, name,
						surname, birth));
				break;
			case WINF:
				m_Studs.insert(name + surname, new WinfStud(m_iNextMNr, name,
						surname, birth));
				break;
			case PEET:
				m_Studs.insert(name + surname, new PeetStud(m_iNextMNr, name,
						surname, birth));
				break;
			}
			++m_iNextFree;
			++m_iNextMNr;
		}
	}

	public void delStud(int iMNr) {
		String key = "";
		for (int i = 0; i < m_Studs.getData().size(); ++i) {
			if (m_Studs.getData().get(i).mnr() == iMNr)
				key = m_Studs.getData().get(i).name()
						+ m_Studs.getData().get(i).name();
		}
		System.out.println("Found Key " + key + " for Matrikelnr " + iMNr);
		m_Studs.remove(key);
		--m_iNextFree;
	}

	public void printHistoAge(PrintStream p) {
		final int fiYoungest = youngest().age();
		final int fiOldest = oldest().age();
		final int[] all = new int[fiOldest - fiYoungest + 1];
		for (int i = 0; i < m_iNextFree; ++i) {
			++all[m_Studs.getData().get(i).age() - fiYoungest];
		}
		for (int i = 0; i < all.length; ++i) {
			if (all[i] > 0)
				p.println(all[i] + " Studenten sind " + (i + fiYoungest)
						+ " Jahre alt");
		}
	}

	public void printHistoExams(PrintStream p) {
		final int[] all = new int[33];
		for (int i = 0; i < m_iNextFree; ++i) {
			++all[m_Studs.getData().get(i).nrOfPassedExams()];
		}
		for (int i = 0; i < all.length; ++i) {
			if (all[i] > 0)
				p.println(all[i] + " Studenten haben " + i
						+ " Examen bestanden");
		}
	}

	public void printAllStuds(PrintStream p) {
		for (int i = 0; i < m_iNextFree; ++i)
			m_Studs.getData().get(i).print(p);
	}

}